﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Odbc;

using cit.CopyDetection.DataObject;

namespace cit.CopyDetection.DatabaseAccess
{
    /// <summary>
    /// Lớp truy cập CSDL cho bảng "documents" và "paragraphs"
    /// </summary>
    public class DocumentDataAccess: ObjectDataAccess
    {
        #region Documents table


        /// <summary>
        /// Lấy tất cả các tài liệu trong CSDL
        /// </summary>
        /// <returns>Danh sách tên các tài liệu</returns>
        public static List<Document> GetDocuments()
        {
            List<Document> documents = new List<Document>();
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "select * from documents order by name";
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, null, connection);

                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        documents.Add(new Document(reader.GetString(0).Trim(), reader.GetString(1).Trim()));
                    }
                }
                connection.Close();

                return documents;
            }
        }

        /// <summary>
        /// Thêm một tài liệu vào CSDL
        /// </summary>
        /// <param name="document">Tài liệu cần thêm</param>
        public static int InsertDocument(Document document)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlInsertCommand = "insert into documents values (?, ?)";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                            new OdbcParameter("@name", OdbcType.Text){Value = document.Name},
                                            new OdbcParameter("@location", OdbcType.Text){Value = document.Location}};
                return OdbcExecuteNonQuery(sqlInsertCommand, parameters, connection);
            }
        }

        /// <summary>
        /// Kiểm tra một tài liệu với định danh nào đó đã tồn tại trong CSDL hay chưa
        /// </summary>
        /// <param name="document">Tài liệu cần kiểm tra</param>
        /// <returns>True, nếu tài liệu đã tồn tại; False, nếu tài liệu chưa tồn tại</returns>
        public static bool IsExist(Document document)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "select * from documents where name = ?";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                                new OdbcParameter("@name", OdbcType.Text){Value = document.Name}};
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, parameters, connection);

                bool isExist = false;
                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    isExist = reader.Read();
                }
                connection.Close();

                return isExist;
            }
        }

        /// <summary>
        /// Xóa một tài liệu trong CSDL
        /// </summary>
        /// <param name="document">Tài liệu cần xóa</param>
        /// <returns>Số dòng dữ liệu bị tác động bởi câu lệnh</returns>
        public static int RemoveDocument(Document document)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlDeleteCommand = "delete from documents where name = ?";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                        new OdbcParameter("@name", OdbcType.Text){Value = document.Name}};
                return OdbcExecuteNonQuery(sqlDeleteCommand, parameters, connection);
            }
        }


        #endregion

        
        #region Paragraphs table


        /// <summary>
        /// Lấy tất cả các đoạn văn bản trong CSDL
        /// </summary>
        /// <returns>Danh sách các đoạn văn bản</returns>
        public static List<Paragraph> GetParagraphs()
        {
            List<Paragraph> paragraphs = new List<Paragraph>();
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "select * from paragraphs order by docname, paranum";
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, null, connection);

                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        paragraphs.Add(new Paragraph(   reader.GetInt32(0),
                                                        reader.GetString(1).Trim(),
                                                        reader.GetInt32(2)));
                    }
                }
                connection.Close();

                return paragraphs;
            }
        }

        /// <summary>
        /// Lấy các đoạn văn bản ứng với tài liệu
        /// </summary>
        /// <param name="documentID">Tài liệu</param>
        /// <returns>Danh sách các đoạn văn bản</returns>
        public static List<Paragraph> GetParagraphs(Document document)
        {
            List<Paragraph> paragraphs = new List<Paragraph>();
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "select * from paragraphs where docname = ? order by paranum";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                            new OdbcParameter("@docname", OdbcType.Text){Value = document.Name}};
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, parameters, connection);

                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        paragraphs.Add(new Paragraph(   reader.GetInt32(0),
                                                        reader.GetString(1).Trim(),
                                                        reader.GetInt32(2)));
                    }
                }
                connection.Close();

                return paragraphs;
            }
        }

        /// <summary>
        /// Thêm một đoạn văn bản vào CSDL
        /// </summary>
        /// <param name="paragraph">Đoạn văn bản cần thêm</param>
        public static int InsertParagraph(Paragraph paragraph)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlInsertCommand = "insert into paragraphs values (?, ?, ?)";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                            new OdbcParameter("@paranum", OdbcType.Int){Value = paragraph.OrdinalNumber},
                                            new OdbcParameter("@docname", OdbcType.Text){Value = paragraph.DocumentName},
                                            new OdbcParameter("@length", OdbcType.Int){Value = paragraph.Length}};
                return OdbcExecuteNonQuery(sqlInsertCommand, parameters, connection);
            }
        }

        /// <summary>
        /// Kiểm tra một đoạn văn bản đã tồn tại trong CSDL hay chưa
        /// </summary>
        /// <param name="paragraph">Đoạn văn bản cần kiểm tra</param>
        /// <returns>True, nếu đoạn văn đã tồn tại; False, nếu đoạn văn bản chưa tồn tại</returns>
        public static bool IsExist(Paragraph paragraph)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlSelectCommand = "select * from paragraphs where paranum = ? and docname = ?";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                                new OdbcParameter("@paranum", OdbcType.Int){Value = paragraph.OrdinalNumber},
                                                new OdbcParameter("@docname", OdbcType.Text){Value = paragraph.DocumentName}};
                OdbcCommand selectCommand = CreateOdbcCommand(sqlSelectCommand, parameters, connection);

                bool isExist = false;
                connection.Open();
                using (OdbcDataReader reader = selectCommand.ExecuteReader())
                {
                    isExist = reader.Read();
                }
                connection.Close();

                return isExist;
            }
        }

        /// <summary>
        /// Xóa đoạn văn bản trong CSDL
        /// </summary>
        /// <param name="paragraph">Đoạn văn bản cần xóa</param>
        /// <returns>Số dòng dữ liệu bị tác động bởi câu lệnh</returns>
        public static int RemoveParagraph(Paragraph paragraph)
        {
            using (OdbcConnection connection = GetOdbcConnection())
            {
                string sqlDeleteCommand = "delete from paragraphs where paranum = ? and docname = ?";
                OdbcParameter[] parameters = new OdbcParameter[] {
                                        new OdbcParameter("@paranum", OdbcType.Text){Value = paragraph.OrdinalNumber},
                                        new OdbcParameter("@docname", OdbcType.Text){Value = paragraph.DocumentName}};
                return OdbcExecuteNonQuery(sqlDeleteCommand, parameters, connection);
            }
        }


        #endregion
    }
}
